package com.zdkj.subway.rca.service.base;

import com.baomidou.mybatisplus.core.toolkit.StringUtils;
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.zdkj.subway.rca.entity.SwCkElectronicReceipt;
import com.zdkj.subway.rca.entity.SwCkElectronicReceiptExport;
import com.zdkj.subway.rca.entity.ViewCkMarketingTicketElec;
import com.zdkj.subway.rca.enums.Payment_TYPE;
import com.zdkj.subway.rca.enums.SW_CK_ELECTRONIC_RECEIPT_CONFIRM_STATUS;
import com.zdkj.subway.rca.enums.SW_CK_ELECTRONIC_RECEIPT_RETURN_ORDER_TYPE;
import com.zdkj.subway.rca.mapper.SwCkElectronicReceiptMapper;
import lombok.extern.slf4j.Slf4j;
import org.springframework.util.CollectionUtils;

import java.math.BigDecimal;
import java.net.URLEncoder;
import java.util.List;
import java.util.Objects;

/**
 * @author cooze
 * @version 1.0.0 创建于 2020/10/25
 **/
@Slf4j
public class SwCkElectronicReceiptServiceBase extends ServiceImpl<SwCkElectronicReceiptMapper, SwCkElectronicReceipt> {

    /**
     * 查出来每个站点、线路的名称并设置值
     *
     * @param res 入参
     */
    public void setLineNameAndStationName(SwCkElectronicReceipt res) {
        SwCkElectronicReceipt lineNameAndStationName = getBaseMapper().getLineNameAndStationName(res);
        if (Objects.isNull(lineNameAndStationName)) {
            return;
        }
        res.setLineName(lineNameAndStationName.getLineName());
        res.setStationName(lineNameAndStationName.getStationName());
    }

    public String excelSheetName(SwCkElectronicReceiptExport export) {
        return String.format("电子账单-%s", SW_CK_ELECTRONIC_RECEIPT_RETURN_ORDER_TYPE.toEnum(export.getReturnOrderType()).get().getName());
    }

    public String exportFileName(SwCkElectronicReceiptExport export) throws Exception {
        return String.format("attachment;filename=%s.xlsx", (URLEncoder.encode(excelSheetName(export), "UTF-8") + System.currentTimeMillis()));
    }

    protected List<SwCkElectronicReceipt> queryExportDataResult(SwCkElectronicReceiptExport export) {
        BigDecimal decimal100 = new BigDecimal("100");
        if (!CollectionUtils.isEmpty(export.getExIdList())) {
            List<SwCkElectronicReceipt> list = baseMapper.selectBatchIds(export.getExIdList());
            for (SwCkElectronicReceipt receipt : list) {
                convertAmount(receipt,decimal100);
            }
            fillExportName(list);
            return list;
        }
        boolean isDateCondition = StringUtils.isNotEmpty(export.getStartDate()) && StringUtils.isNotEmpty(export.getEndDate());
        SwCkElectronicReceipt swCkElectronicReceipt = new SwCkElectronicReceipt();
        swCkElectronicReceipt.setReturnOrderType(export.getReturnOrderType());
        if (StringUtils.isNotEmpty(export.getConfirmStatus())) {
            swCkElectronicReceipt.setConfirmStatus(export.getConfirmStatus());
        }
        if (StringUtils.isNotEmpty(export.getLineCode())) {
            swCkElectronicReceipt.setLineCode(export.getLineCode());
        }
        if (StringUtils.isNotEmpty(export.getStationCode())) {
            swCkElectronicReceipt.setStationCode(export.getStationCode());
        }
        if (StringUtils.isNotEmpty(export.getTicketType())) {
            swCkElectronicReceipt.setTicketType(export.getTicketType());
        }
        List<SwCkElectronicReceipt> list = baseMapper.selectList(Wrappers.query(swCkElectronicReceipt).lambda()
                .between(isDateCondition, SwCkElectronicReceipt::getBookkeepingTime, export.getStartDate(), export.getEndDate()));
        for (SwCkElectronicReceipt receipt : list) {
            convertAmount(receipt,decimal100);
        }
        fillExportName(list);
        return list;
    }

    private void convertAmount(SwCkElectronicReceipt receipt, BigDecimal decimal100) {
        receipt.setSaleAmount(receipt.getSaleAmount().divide(decimal100));
        if(receipt.getMailingCost() != null){
            receipt.setMailingCost(receipt.getMailingCost().divide(decimal100));
        }
        receipt.setHandServiceMoney(receipt.getHandServiceMoney().divide(decimal100));
        receipt.setDeductHandServiceMoney(receipt.getDeductHandServiceMoney().divide(decimal100));
        receipt.setBankAccountBalance(receipt.getBankAccountBalance().divide(decimal100));
        receipt.setDiffElecAmount(receipt.getDiffElecAmount().divide(decimal100));
        receipt.setDiscountAmount(receipt.getDiscountAmount().divide(decimal100));
        receipt.setBankElecOrderAmount(receipt.getBankElecOrderAmount().divide(decimal100));
        receipt.setDiffAccountAmount(receipt.getDiffAccountAmount().divide(decimal100));
    }

    public void fillExportName(List<SwCkElectronicReceipt> res) {
        res.forEach(this::setLineNameAndStationName);
        fillName(res);
    }

    public void fillName(List<SwCkElectronicReceipt> res) {
        res.forEach(r -> {
            Payment_TYPE.toEnum(r.getPaymentType()).ifPresent(pt -> r.setPaymentTypeName(pt.getName()));
            SW_CK_ELECTRONIC_RECEIPT_CONFIRM_STATUS.toEnum(r.getConfirmStatus()).ifPresent(pt -> r.setConfirmStatusName(pt.getName()));
        });

    }

    public void aggregationCkMarketingTicketElec(List<ViewCkMarketingTicketElec> list) {
        if(CollectionUtils.isEmpty(list)){
            log.warn("aggregationCkMarketingTicketElec failure cause by: result is empty.");
            return;
        }
        ViewCkMarketingTicketElec elec = new ViewCkMarketingTicketElec();
        //"汇总数据标识，（汇总数据一般为最后一条数据，保险起见加一个标识），默认值 0；0-非汇总数据，1-汇总数据"
        elec.setAggreType("1");
        elec.setOfflineSellAmount(list.stream().map(ViewCkMarketingTicketElec::getOfflineSellAmount).reduce(BigDecimal::add).get());
        elec.setOfflineBankReceipts(list.stream().map(ViewCkMarketingTicketElec::getOfflineBankReceipts).reduce(BigDecimal::add).get());
        elec.setTransferSellAmount(list.stream().map(ViewCkMarketingTicketElec::getTransferSellAmount).reduce(BigDecimal::add).get());
        elec.setTransferBankReceipts(list.stream().map(ViewCkMarketingTicketElec::getTransferBankReceipts).reduce(BigDecimal::add).get());
        elec.setGroupPurchaseCash(list.stream().map(ViewCkMarketingTicketElec::getGroupPurchaseCash).reduce(BigDecimal::add).get());
        elec.setGroupPurchaseWechat(list.stream().map(ViewCkMarketingTicketElec::getGroupPurchaseWechat).reduce(BigDecimal::add).get());
        elec.setGroupPurchaseAlipay(list.stream().map(ViewCkMarketingTicketElec::getGroupPurchaseAlipay).reduce(BigDecimal::add).get());
        elec.setGroupPurchaseBankTransfer(list.stream().map(ViewCkMarketingTicketElec::getGroupPurchaseBankTransfer).reduce(BigDecimal::add).get());
        elec.setGroupPurchaseTotal(list.stream().map(ViewCkMarketingTicketElec::getGroupPurchaseTotal).reduce(BigDecimal::add).get());
        elec.setGroupPurchaseBankReceipts(list.stream().map(ViewCkMarketingTicketElec::getGroupPurchaseBankReceipts).reduce(BigDecimal::add).get());
        elec.setDiffOfflineTicket(list.stream().map(ViewCkMarketingTicketElec::getDiffOfflineTicket).reduce(BigDecimal::add).get());
        elec.setDiffTransferTicket(list.stream().map(ViewCkMarketingTicketElec::getDiffTransferTicket).reduce(BigDecimal::add).get());
        elec.setDiffGroupSell(list.stream().map(ViewCkMarketingTicketElec::getDiffGroupSell).reduce(BigDecimal::add).get());
        list.add(elec);
    }


    public enum EXPORT_EXCEL_TPL {
        TRANSFER_ACCOUNTS("1", "转账", "classpath:/static/excel/template/export/SwCkElectronicReceiptTransferAccounts.xlsx"),
        GROUP_BUY("2", "团购", "classpath:/static/excel/template/export/SwCkElectronicReceiptGroupBuy.xlsx"),
        PLATFORM_DATA("3", "平台", "classpath:/static/excel/template/export/SwCkElectronicReceiptPlatformData.xlsx"),
        ;
        private String code;
        private String desc;

        private String tplClasspath;

        EXPORT_EXCEL_TPL(String code, String desc, String tplClasspath) {
            this.code = code;
            this.desc = desc;
            this.tplClasspath = tplClasspath;
        }

        public String getCode() {
            return code;
        }

        public String getTplClasspath() {
            return tplClasspath;
        }

        public String getDesc() {
            return desc;
        }

        public static EXPORT_EXCEL_TPL toEnum(String code) {
            if (org.springframework.util.StringUtils.isEmpty(code)) {
                return null;
            }
            for (EXPORT_EXCEL_TPL E : EXPORT_EXCEL_TPL.values()) {
                if (E.getCode().equals(code)) {
                    return E;
                }
            }
            return null;
        }
    }
}
